package com.niit.base

import java.util.Scanner
import scala.io.StdIn



/*
总结：
 1.三引号表达式用来保存大量文本，同时可以保留换行、空格等格式
 2.惰性赋值，当有一些自定义的常量数据较大的时候，而这些数据并不是马上去加载到ＪＶＭ内存中，就可以使用惰性赋值提高效率　
    格式：lazy　val　变量名　＝　数据
 3.标识符就是给变量、方法、类起名字的，Scala 和 Java 中的标识符非常相似。
    命名规则：
    必须由 大小写英文字母、数字、下划线_、美元符号$ 四部分任意组合。
    数字不能开头。
    不能和 Scala 关键字重名。
    最好做到见名知意。
    命名规范：
    变量或方法：小驼峰命名，从第二个单词开始每个单词首字母大写。
    类或特质：大驼峰命名，每个单词的首字母都大写。
    包：全部小写，一般是公司域名反写，多级包用.隔开。
 4.数据类型：
          所有类型都以大写字母开头
          整形使用 Int 而不是 Integer
         定义变量可以不写类型，让编译器自动推断
         默认整形是 Int，默认浮点型是 Double
         Any 是所有类型的父类，相当于 Java 中的 Object 类。
      Scala 的类型关系
        AnyVal 是所有数值类型的父类，AnyRef 是所有引用类型的父类。
        Unit 类似于 Java 中的 void，一般作为返回值。
        Null 是所有引用类型的子类，只有一个实例 null。
        Nothing 是所有数据类型的子类，不能创建该类型实例，一般结合异常使用。
   5.类型转换
        自动类型转换：用大数据类型接收小的数据类型
        强制类型转换：用小数据类型接收大的数据类型，会损失精度 val/var 变量名:数据类型 = 数值.toXxx  (Xxx：要转换的数据类型)
        值类型和String类型之间的转换
            格式一 var/val 变量名:String = 值类型 + ""  (任意类型对字符串进行拼接，最终类型为字符串)
            格式二 var/val 变量名:String = 值类型.toString
       String类型变成 值类型
            val/var 变量名:数据类型 = 数值.toXxx  (Xxx：要转换的数据类型)
    6.键盘录入：
      字符串的键盘录入：StdIn.readLine()
      整数的键盘录入：StnIn.readInt()
   7.算数运算符
      包括 +（加号）、-（减号）、*（乘号）、/（除号）、%（取余）。
      Scala中没有 ++，--这两个运算符。
     a % b，底层是 a - a/b * b
   8.赋值运算符
      基本赋值运算符 =
      扩展赋值运算符 +=、-=、*=、/=、%=
   9.关系运算符
   包括>、>=、<、<=、==、!=
   最终结果一定是 true 或 false。
   如果需要比较数据值，使用==或者!=，如果比较引用值需要使用 eq 方法。
  10.包括 &&、|| 、 !
    最终结果一定是 true 或 false。
    &&:两者都是成立，则返回值为true。其中有一个不成立，则返回值为false
    ||:两者中有一个成立，则返回为true。
    !:相反
   11.顺序结构：程序按照从上至下、从左至右的顺序依次逐行执行，中间没有任何判断和跳转。顺序结构是 Scala 中的默认流程结构。
   12.if-else if -else :如果if的条件成立，则执行if的代码块。如果if不成立，则依次判断执行else if的条件是否成立。如果以上都不成立，则执行else
   13.Scala中没有三目运算符，替换方案为：val res = if(2>1) 2 else 1
   14.代码块：代码块表达式格式：val a= { 代码 } 注意：最后一条语句才是最后的返回值
   15.10.for 循环 格式：for(i <- 表达式/集合)
   16.or循环的守卫 格式 for表达式中，可以添加if判断语句，这个if判断就称之为守卫。我们可以使用守卫让for循环变得更简洁 格式： for(i <- 表达式/集合 if 表达式)
   17.Scala要想使用break需要在for循环外面在套一层breakable 。没有continue关键字
   18.方法：def 方法名(参数名:参数类型,参数名:参数类型):[return type]={
  *       方法体
  *     }
  *     注意：参数列表的参数类型不能省略
        返回值类型可以省略，由 Scala 编译器自动推断
        返回值可以不写 return ，默认就是块表达式的值
 */

object Base_03 {
  def main(args: Array[String]): Unit = {



    //1.三引号  '' :字符  ""：字符串
    //如果有大段的文本信息，就可以使用三引号进行保存。三引号所保存的字符串信息就同样的保留格式
//    val str1 = "lalalalalal" +
//      "lalallala"
//    println(str1)
//    val str2 = """盼望着，盼望着，东风来了，春天的脚步近了。一切都像刚睡醒的样子，欣欣然张开了眼。山朗润起来了，水涨起来了，太阳的脸红起来了。
//                 |小草偷偷地从土里钻出来，嫩嫩的，绿绿的。园子里，田野里，瞧去，一大片一大片满是的。坐着，躺着，打两个滚，踢几脚球，赛几趟跑，捉几回迷藏。风轻悄悄的，草软绵绵的。
//                 |桃树、杏树、梨树，你不让我，我不让你，都开满了花赶趟儿。红的像火，粉的像霞，白的像雪。花里带着甜味儿；闭了眼，树上仿佛已经满是桃儿、杏儿、梨儿。
//                 |花下成千成百的蜜蜂嗡嗡地闹着，大小的蝴蝶飞来飞去。野花遍地是：杂样儿，有名字的，没名字的，散在草丛里，像眼睛，像星星，还眨呀眨的。
//                 |“吹面不寒杨柳风”，不错的，像母亲的手抚摸着你。风里带来些新翻的泥土的气息，混着青草味儿，还有各种花的香，都在微微润湿的空气里酝酿。
//                 |鸟儿将巢安在繁花嫩叶当中，高兴起来了，呼朋引伴地卖弄清脆的喉咙，唱出宛转的曲子，与轻风流水应和着。牛背上牧童的短笛，这时候也成天嘹亮地响着。
//                 |雨是最寻常的，一下就是三两天。可别恼。看，像牛毛，像花针，像细丝，密密地斜织着，人家屋顶上全笼着一层薄烟。树叶儿却绿得发亮，小草儿也青得逼你的眼。
//                 |傍晚时候，上灯了，一点点黄晕的光，烘托出一片安静而和平的夜。石桥边，有撑起伞慢慢走着的人，地里还有工作的农民，披着蓑戴着笠。他们的房屋，稀稀疏疏的在雨里静默着。
//                 |春天像刚落地的娃娃，从头到脚都是新的，它生长着。春天像小姑娘，
//                 |花枝招展的，笑着，走着。春天像健壮的青年，有铁一般的胳膊和腰脚，领着我们上前去。""".stripMargin
//    println(str2)

    //2.惰性赋值。当使用惰性赋值的时候，该变量用到的时候才会加载到内存当中。格式 lazy val 变量名 = 数值
    lazy val name = "张三"
    println(name)

    //3.1 数值类型转换  自动数据类型指的是：用大的数据类型去装小的数据类型
    //从小到大数据类型依次为：Byte - Short - Int - Long - Float - Double
    var a:Int = 10
    var b:Long  = a
    var c:Double = 3 + 3.14
    println(c)
    //3.2强制类型转换 将范围大的数据类型值通过一定格式转换为范围小的数据类型值（可能会造成精度缺失）。
    //val/var 变量名:数据类型 = 数值.toXxx  (Xxx：要转换的数据类型)
    val d:Double = 5.21
    val e:Int = d.toInt
    println(e)
    //3.2值类型和String类型之间的转换
    // 格式一 var/val 变量名:String = 值类型 + ""  (任意类型对字符串进行拼接，最终类型为字符串)
    var f:String = 3.14 + ""
    println(f)
    //格式二 var/val 变量名:String = 值类型.toString
    var g:String = 999.toString
    println(g)
    //3.3String类型变成 值类型
    //val/var 变量名:数据类型 = 数值.toXxx  (Xxx：要转换的数据类型)
    val h:String ="100"
    val i:Int  = h.toInt
    val j:Float = h.toFloat
    println(i,j)
    val k:String = "true"
    val l:Boolean = k.toBoolean
    //val m:Int = k.toInt  //注意：字符串类型的Boolean 是无法转换到Int 。Boolean也无法转换为值类型
    println(l)

    //4.键盘录入
    //字符串的键盘录入：StdIn.readLine()
    //整数的键盘录入：StnIn.readInt()
    //println("请输入一个字符串："+StdIn.readLine())
//    println("请输入你们最大愿望：")
//    val str = StdIn.readLine()
//    println("我的最大的愿望：" + str)

    //5.余数
//    var q = 27%5  //27 - 27/5 * 5  = 27 -25
//    println(q)

    //a += b // 完整版：a = a + b

//    var w ="abc".eq("efg")
//    println(w)

    //6.逻辑运算符
//    println( 1>2 && 2>1)//false
//    println( 2>0 && 11>8)//true
//
//    println( 1>2 || 2>1)//true
//    println( 2>0 || 11>8)//true
//
//    println( !(1>2 || 2>1))//false
//    println( !(2>0 && 11>8) )//false

    //7.if -else if -else
    var score = 80
    if(score>=90 && score<=100){
      println("你很优秀")
    }else if (score>=80 && score<90){
      println("一般般")
    }else if (score>=0 && score<80){
      println("努力吧你")
    }else{
      println("成绩无效")
    }
    //8.int a = 2>1 ? 2 : 1 三元（目）运算符。Scala中没有三目运算符，替换方案为： 写
    val res = if(2>1) 2 else 1
    println(res)
    //9.块表达式 { 代码 }  ——> 代码块 写
    //代码块表达式格式：val a= { 代码 }
    val kuai = { //6
      if(2>1){
        println("成立")
      }
      1+1 // 2
      3+3 // 6 最后一条语句才是最后的返回值
    }
    println(kuai)
    //10.for 循环  写
    //格式：for(i <- 表达式/集合)
    //需求:输出10次。Hello Scala。
    for(i <- 1 to 10){ // [1,10]
      println("Hello Scala",i)
    }
    val num = 1 to 10//[1,2,3,4,5,6,7,9,10]
    for(i <- num){ // [1,10]
      println("Hello Scala",i)
    }
    //11.for循环的守卫 格式 for表达式中，可以添加if判断语句，这个if判断就称之为守卫。我们可以使用守卫让for循环变得更简洁 写
    //格式： for(i <- 表达式/集合 if 表达式)
    //利用守卫，1-10之间输出可以被二整除的数字
    for (i <- num if i %2==0){
      println(i)
    }
    //12.for推导式 写 for循环也是有返回值的，可以使用yield对for循环的数据进行范围为一个集合
//    val v = for(i <- 1 to 10) yield i * 10; //v [10,20,30,40,50,60,70,80,90,100]
//    println(v)
    //13.while 和 do-while
    //需求：输出 1-10
    var count = 1;
//    while (count <=10){
//      println(count)//1 2 …………
//      count += 1
//    }

//    do{
//      println(count)
//      count += 1
//    }while(count<=10)

    //14.break 和 continue  ---> Scala要想使用break需要在for循环外面在套一层breakable 。没有continue关键字
    import scala.util.control.Breaks.{break, breakable}
//    breakable{
//      for(i <- 1 to 10){
//        //当i为5的时候结束循环
//        if(i==5){
//          break()
//        }else{
//          println(i)
//        }
//      }
//    }
    //需求：用for 打印1-10。但是不输出能被2整除的数字
//    for (i <- 1 to 10){
//      breakable{
//        if (i %2==0){
//          break()
//        }else{
//          println(i)
//        }
//      }
//    }
  //15.方法
  /*
  *  def 方法名(参数名:参数类型,参数名:参数类型):[return type]={
  *       方法体
  *     }
  *注意：参数列表的参数类型不能省略
        返回值类型可以省略，由 Scala 编译器自动推断
        返回值可以不写 return ，默认就是块表达式的值
  * */
    val max = getMax(b=10,a=20);//实参 （实际上的参数） 真实的数据
    println(max) //20

    val sum = getSum(1,2,3,4,5,6,7,8,9,10,11)
    println(sum)
  }

  //方式一：标准写法。。 需求：定义方法，来获取两个值中的最大值
  //默认参数。直接在形参上定义真实数据。如果没有实参的传入，那么a,b就默认为6,7
  //带名参数：在传入实参的时候指定给哪个形参传数据
  def getMax(a:Int=6,b:Int=7):Int={//a:Int,b:Int 形参 （形式上的参数） 占位的作用
     return if(a>b) a else b
  }
  //方式二：优化写法
  //def getMax(a:Int,b:Int) = if(a>b) a else b

  //变长参数 ：如果方法的参数是不固定的，可以将该方法的参数定义为变长参数
  /*
  def 方法名(参数名:参数类型*)[: 返回值类型] = {
	    方法体
    }
    传入诺干个整数，计算其总和
   */
  def getSum(a:Int*)={//可以把变长参数看作一个数据或集合
    a.sum
  }
}
